/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dal/allocator.h"
#include "dal/config_loader.h"
#include "dal_rticonnextdds/converter/StatusConverter.hpp"
#include "dal_rticonnextdds/converter/StatusMaskConverter.hpp"
#include "dal_rticonnextdds/converter/QosConverter.hpp"
#include "dal_rticonnextdds/converter/RetTypeConverter.hpp"
#include "dal_rticonnextdds/converter/InstanceHandleConverter.hpp"
#include "dal_rticonnextdds/converter/GuidConverter.hpp"
#include "dal_rticonnextdds/listener_impl/PublisherListenerImpl.hpp"
#include "dal_rticonnextdds/listener_impl/DataWriterListenerImpl.hpp"
#include "dal_rticonnextdds/utils/log.hpp"
#include "dal_rticonnextdds/utils/EntityGetter.hpp"
#include "dal_rticonnextdds/type_support/RtiTypeSupportImpl.hpp"
#include "dal_rticonnextdds/utils/EntityMappingManager.hpp"

const dal_instance_handle_t DAL_HANDLE_NIL = {0, 0, 0, 0};

// PUBLISHER
dal_publisher_listener_t*
dal_create_publisher_listener(dal_publisher_listener_callbacks_t callbacks)
{
    dal_publisher_listener_t* listener = dal_publisher_listener_allocate();
    if (listener == nullptr) {
        return nullptr;
    }
    listener->handle_ = new PublisherListenerImpl(callbacks);
    if (!listener->handle_) {
        LOG_ERROR() << "PublisherListenerImpl memory allocation failed." << LOG_ENDL;
        dal_publisher_listener_free(listener);
        return nullptr;
    }

    return listener;
}

dal_ret_t dal_delete_publisher_listener(dal_publisher_listener_t* listener)
{
    if (!listener || !listener->handle_) {
        LOG_ERROR_WITH_LOCATION() << "listener is invalid." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    PublisherListenerImpl* listener_impl =
        reinterpret_cast<PublisherListenerImpl*>(listener->handle_);
    if (listener_impl->ref_count_.Get() > 0) {
        LOG_ERROR() << "can't delete publisher listener because it's entity still exist."
                    << LOG_ENDL;
        return DAL_RETCODE_PRECONDITION_NOT_MET;
    }

    delete listener_impl;
    dal_publisher_listener_free(listener);
    reinterpret_cast<dal_publisher_listener_t*>(listener)->handle_ = nullptr;

    return DAL_RETCODE_OK;
}

dal_publisher_t* dal_domain_participant_create_publisher(dal_domain_participant_t* participant,
                                                         dal_publisher_qos_t* qos,
                                                         dal_publisher_listener_t* listener,
                                                         dal_status_mask_t mask)
{
    dal_ret_t d_ret = DAL_RETCODE_OK;

    DDS_DomainParticipant* r_participant = get_rtidds_domain_participant(participant);
    if (!r_participant) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds participant failed." << LOG_ENDL;
        return nullptr;
    }

    dal_publisher_t* d_pub = dal_publisher_allocate();
    if (!d_pub) {
        LOG_ERROR_WITH_LOCATION() << "dal publisher allocate failed." << LOG_ENDL;
        return nullptr;
    }

    DDS_PublisherQos* r_qos = new DDS_PublisherQos();
    DDS_DomainParticipant_get_default_publisher_qos(r_participant, r_qos);
    d_ret = QosConverter::GetInstance()->ConvertPublisherQosFromDalToRtidds(qos, r_qos);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert publisher qos failed." << LOG_ENDL;
        dal_publisher_free(d_pub);
        return nullptr;
    }

    DDS_StatusMask c_mask = DDS_STATUS_MASK_NONE;
    d_ret = StatusMaskConverter::GetInstance()->ConvertStatusMaskFromDalToRtidds(mask, &c_mask);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert ststu mask failed." << LOG_ENDL;
        dal_publisher_free(d_pub);
        return nullptr;
    }

    PublisherListenerImpl* r_listener_impl =
        listener ? reinterpret_cast<PublisherListenerImpl*>(listener->handle_) : nullptr;

    DDS_Publisher* r_pub = DDS_DomainParticipant_create_publisher(
        r_participant, r_qos, r_listener_impl ? r_listener_impl->getListener() : NULL, c_mask);

    delete r_qos;
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "create publisher failed." << LOG_ENDL;
        dal_publisher_free(d_pub);
        return nullptr;
    }

    EntityMappingAddPublisher(r_pub, d_pub);
    d_pub->handle_ = new DalPublisherImpl(r_pub, r_listener_impl);
    return d_pub;
}

dal_publisher_t*
dal_domain_participant_create_publisher_with_profile(dal_domain_participant_t* participant,
                                                     dal_publisher_qos_t* qos,
                                                     const char* profile_name,
                                                     dal_publisher_listener_t* listener,
                                                     dal_status_mask_t mask)
{
    if (!profile_name || strlen(profile_name) == 0) {
        return dal_domain_participant_create_publisher(participant, qos, listener, mask);
    }

    dal_ret_t d_ret = DAL_RETCODE_OK;

    DDS_DomainParticipant* r_participant = get_rtidds_domain_participant(participant);
    if (!r_participant) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds participant failed." << LOG_ENDL;
        return nullptr;
    }

    dal_publisher_t* d_pub = dal_publisher_allocate();
    if (!d_pub) {
        LOG_ERROR_WITH_LOCATION() << "dal publisher allocate failed." << LOG_ENDL;
        return nullptr;
    }

    DDS_DomainParticipantFactory* factory = DDS_DomainParticipantFactory_get_instance();
    DDS_PublisherQos* r_qos = new DDS_PublisherQos();
    DDS_ReturnCode_t r_ret = DDS_DomainParticipantFactory_get_publisher_qos_from_profile(
        factory, r_qos, "dal_rticonnext_qos_profile_lib", profile_name);
    if (r_ret != DDS_RETCODE_OK) {
        d_ret = QosConverter::GetInstance()->ConvertPublisherQosFromDalToRtidds(qos, r_qos);
        if (DAL_RETCODE_OK != d_ret) {
            LOG_ERROR_WITH_LOCATION() << "convert publisher qos failed." << LOG_ENDL;
            dal_publisher_free(d_pub);
            return nullptr;
        }
    }

    DDS_StatusMask c_mask = DDS_STATUS_MASK_NONE;
    d_ret = StatusMaskConverter::GetInstance()->ConvertStatusMaskFromDalToRtidds(mask, &c_mask);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert ststu mask failed." << LOG_ENDL;
        dal_publisher_free(d_pub);
        return nullptr;
    }

    PublisherListenerImpl* r_listener_impl =
        listener ? reinterpret_cast<PublisherListenerImpl*>(listener->handle_) : nullptr;

    DDS_Publisher* r_pub = DDS_DomainParticipant_create_publisher(
        r_participant, r_qos, r_listener_impl ? r_listener_impl->getListener() : NULL, c_mask);

    delete r_qos;
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "create publisher failed." << LOG_ENDL;
        dal_publisher_free(d_pub);
        return nullptr;
    }

    EntityMappingAddPublisher(r_pub, d_pub);
    d_pub->handle_ = new DalPublisherImpl(r_pub, r_listener_impl);
    return d_pub;
}

dal_ret_t dal_domain_participant_delete_publisher(dal_domain_participant_t* participant,
                                                  dal_publisher_t* pub)
{
    DDS_DomainParticipant* r_participant = get_rtidds_domain_participant(participant);
    if (!r_participant) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds participant failed." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DDS_Publisher* r_pub = get_rtidds_publisher(pub);
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds publisher failed." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DDS_ReturnCode_t ret = DDS_DomainParticipant_delete_publisher(r_participant, r_pub);
    if (ret != DDS_RETCODE_OK) {
        LOG_ERROR_WITH_LOCATION() << "delete publisher failed." << LOG_ENDL;
        return DAL_RETCODE_ERROR;
    }

    EntityMappingRemovePublisher(r_pub);

    DalPublisherImpl* pub_impl = reinterpret_cast<DalPublisherImpl*>(pub->handle_);
    delete pub_impl;
    dal_publisher_free(pub);
    reinterpret_cast<dal_publisher_t*>(pub)->handle_ = nullptr;

    return DAL_RETCODE_OK;
}

// DATAWRITER
dal_datawriter_listener_t*
dal_create_datawriter_listener(dal_datawriter_listener_callbacks_t callbacks)
{
    dal_datawriter_listener_t* listener = dal_datawriter_listener_allocate();
    if (listener == nullptr) {
        return nullptr;
    }
    listener->handle_ = new DataWriterListenerImpl(callbacks);
    if (!listener->handle_) {
        LOG_ERROR() << "DataWriterListenerImpl memory allocation failed." << LOG_ENDL;
        dal_datawriter_listener_free(listener);
        return nullptr;
    }

    return listener;
}

dal_ret_t dal_delete_datawriter_listener(dal_datawriter_listener_t* listener)
{
    if (!listener || !listener->handle_) {
        LOG_ERROR_WITH_LOCATION() << "listener is invalid." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DataWriterListenerImpl* listener_impl =
        reinterpret_cast<DataWriterListenerImpl*>(listener->handle_);
    if (listener_impl->ref_count_.Get() > 0) {
        LOG_ERROR() << "can't delete datawriter listener because it's entity still exist."
                    << LOG_ENDL;
        return DAL_RETCODE_PRECONDITION_NOT_MET;
    }

    delete listener_impl;
    dal_datawriter_listener_free(listener);
    reinterpret_cast<dal_datawriter_listener_t*>(listener)->handle_ = nullptr;

    return DAL_RETCODE_OK;
}

static void optimize_datawriter_qos_for_large_data(DDS_DataWriterQos* qos)
{
    qos->protocol.rtps_reliable_writer.min_send_window_size =
        DAL_CONNEXT_LARGE_DATA_SEND_WINDOW_SIZE_MIN;
    qos->protocol.rtps_reliable_writer.max_send_window_size =
        DAL_CONNEXT_LARGE_DATA_SEND_WINDOW_SIZE_MAX;
    qos->protocol.rtps_reliable_writer.heartbeats_per_max_samples =
        DAL_CONNEXT_LARGE_DATA_SEND_WINDOW_SIZE_MAX;

    qos->protocol.rtps_reliable_writer.heartbeat_period = DAL_CONNEXT_LARGE_DATA_HEARTBEAT_PERIOD;
    qos->protocol.rtps_reliable_writer.late_joiner_heartbeat_period =
        DAL_CONNEXT_LARGE_DATA_HEARTBEAT_PERIOD_FAST;
    qos->protocol.rtps_reliable_writer.fast_heartbeat_period =
        DAL_CONNEXT_LARGE_DATA_HEARTBEAT_PERIOD_FAST;

    qos->protocol.rtps_reliable_writer.max_nack_response_delay = DDS_DURATION_ZERO;

    qos->protocol.rtps_reliable_writer.high_watermark = DAL_CONNEXT_LARGE_DATA_SEND_WINDOW_SIZE_MIN;
    qos->protocol.rtps_reliable_writer.low_watermark = 0;

    qos->protocol.rtps_reliable_writer.max_heartbeat_retries = 500;
}

dal_datawriter_t* dal_publisher_create_datawriter(dal_publisher_t* pub,
                                                  dal_topic_t* topic,
                                                  dal_datawriter_qos_t* qos,
                                                  dal_datawriter_listener_t* listener,
                                                  dal_status_mask_t mask)
{
    dal_ret_t d_ret = DAL_RETCODE_OK;

    DDS_Publisher* r_pub = get_rtidds_publisher(pub);
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds publisher failed." << LOG_ENDL;
        return nullptr;
    }

    DDS_Topic* r_topic = get_rtidds_topic(topic);
    if (!r_topic) {
        LOG_ERROR_WITH_LOCATION() << "rtidds topic is invalid." << LOG_ENDL;
        return nullptr;
    }

    dal_datawriter_t* d_writer = dal_datawriter_allocate();
    if (!d_writer) {
        LOG_ERROR_WITH_LOCATION() << "dal datawriter allocate failed." << LOG_ENDL;
        return nullptr;
    }

    if (!topic->type_support_impl_) {
        LOG_ERROR_WITH_LOCATION() << "topic type support is invalid." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }
    d_writer->type_support_impl_ = topic->type_support_impl_;

    DDS_DataWriterQos* r_qos = new DDS_DataWriterQos();
    DDS_Publisher_get_default_datawriter_qos(r_pub, r_qos);
    d_ret = QosConverter::GetInstance()->ConvertDataWriterQosFromDalToRtidds(qos, r_qos);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert datawriter qos failed." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }

    // for async (set in conf file)
    // r_qos->publish_mode.kind = DDS_ASYNCHRONOUS_PUBLISH_MODE_QOS;

    // if type is unbound set property to force allocation of samples from heap
    const RtiTypeSupportImpl* tsImpl =
        reinterpret_cast<const RtiTypeSupportImpl*>(d_writer->type_support_impl_);
    DAL_Connext_MessageTypeSupport* ts = tsImpl->cxtMsgTs_;
    if (ts->unbounded()) {
        DDS_PropertyQosPolicyHelper_add_property(
            &r_qos->property,
            "dds.data_writer.history.memory_manager.fast_pool.pool_buffer_max_size",
            "0",
            DDS_BOOLEAN_FALSE);
    }
    // optimize when sending large data
    const int LARGE_DATA_SER_SIZE = 1048576;
    if (ts->type_serialized_size_max() >= LARGE_DATA_SER_SIZE) {
        optimize_datawriter_qos_for_large_data(r_qos);
    }

    DataWriterListenerImpl* r_listener_impl =
        listener ? reinterpret_cast<DataWriterListenerImpl*>(listener->handle_) : nullptr;

    DDS_StatusMask r_mask = DDS_STATUS_MASK_NONE;
    d_ret = StatusMaskConverter::GetInstance()->ConvertStatusMaskFromDalToRtidds(mask, &r_mask);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert status mask failed." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }

    DDS_DataWriter* r_writer = DDS_Publisher_create_datawriter(
        r_pub, r_topic, r_qos, r_listener_impl ? r_listener_impl->getListener() : NULL, r_mask);
    delete r_qos;
    if (!r_writer) {
        LOG_ERROR_WITH_LOCATION() << "create datawriter failed." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }

    EntityMappingAddDataWriter(r_writer, d_writer);
    d_writer->handle_ = new DalDataWriterImpl(r_writer, r_listener_impl);
    return d_writer;
}

dal_datawriter_t* dal_publisher_create_datawriter_with_profile(dal_publisher_t* pub,
                                                               dal_topic_t* topic,
                                                               dal_datawriter_qos_t* qos,
                                                               const char* profile_name,
                                                               dal_datawriter_listener_t* listener,
                                                               dal_status_mask_t mask)
{
    if (!profile_name || strlen(profile_name) == 0) {
        return dal_publisher_create_datawriter(pub, topic, qos, listener, mask);
    }

    dal_ret_t d_ret = DAL_RETCODE_OK;

    DDS_Publisher* r_pub = get_rtidds_publisher(pub);
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds publisher failed." << LOG_ENDL;
        return nullptr;
    }

    DDS_Topic* r_topic = get_rtidds_topic(topic);
    if (!r_topic) {
        LOG_ERROR_WITH_LOCATION() << "rtidds topic is invalid." << LOG_ENDL;
        return nullptr;
    }

    dal_datawriter_t* d_writer = dal_datawriter_allocate();
    if (!d_writer) {
        LOG_ERROR_WITH_LOCATION() << "dal datawriter allocate failed." << LOG_ENDL;
        return nullptr;
    }

    if (!topic->type_support_impl_) {
        LOG_ERROR_WITH_LOCATION() << "topic type support is invalid." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }
    d_writer->type_support_impl_ = topic->type_support_impl_;

    DDS_DomainParticipantFactory* factory = DDS_DomainParticipantFactory_get_instance();
    DDS_DataWriterQos* r_qos = new DDS_DataWriterQos();
    DDS_ReturnCode_t r_ret = DDS_DomainParticipantFactory_get_datawriter_qos_from_profile(
        factory, r_qos, "dal_rticonnext_qos_profile_lib", profile_name);
    if (r_ret != DDS_RETCODE_OK) {
        d_ret = QosConverter::GetInstance()->ConvertDataWriterQosFromDalToRtidds(qos, r_qos);
        if (DAL_RETCODE_OK != d_ret) {
            LOG_ERROR_WITH_LOCATION() << "convert datawriter qos failed." << LOG_ENDL;
            dal_datawriter_free(d_writer);
            return nullptr;
        }
    }

    // for async (set in conf file)
    // r_qos->publish_mode.kind = DDS_ASYNCHRONOUS_PUBLISH_MODE_QOS;

    // if type is unbound set property to force allocation of samples from heap
    const RtiTypeSupportImpl* tsImpl =
        reinterpret_cast<const RtiTypeSupportImpl*>(d_writer->type_support_impl_);
    DAL_Connext_MessageTypeSupport* ts = tsImpl->cxtMsgTs_;
    if (ts->unbounded()) {
        DDS_PropertyQosPolicyHelper_add_property(
            &r_qos->property,
            "dds.data_writer.history.memory_manager.fast_pool.pool_buffer_max_size",
            "0",
            DDS_BOOLEAN_FALSE);
    }
    // optimize when sending large data
    const int LARGE_DATA_SER_SIZE = 1048576;
    if (ts->type_serialized_size_max() >= LARGE_DATA_SER_SIZE) {
        optimize_datawriter_qos_for_large_data(r_qos);
    }

    DataWriterListenerImpl* r_listener_impl =
        listener ? reinterpret_cast<DataWriterListenerImpl*>(listener->handle_) : nullptr;

    DDS_StatusMask r_mask = DDS_STATUS_MASK_NONE;
    d_ret = StatusMaskConverter::GetInstance()->ConvertStatusMaskFromDalToRtidds(mask, &r_mask);
    if (DAL_RETCODE_OK != d_ret) {
        LOG_ERROR_WITH_LOCATION() << "convert status mask failed." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }

    DDS_DataWriter* r_writer = DDS_Publisher_create_datawriter(
        r_pub, r_topic, r_qos, r_listener_impl ? r_listener_impl->getListener() : NULL, r_mask);
    delete r_qos;
    if (!r_writer) {
        LOG_ERROR_WITH_LOCATION() << "create datawriter failed." << LOG_ENDL;
        dal_datawriter_free(d_writer);
        return nullptr;
    }

    EntityMappingAddDataWriter(r_writer, d_writer);
    d_writer->handle_ = new DalDataWriterImpl(r_writer, r_listener_impl);
    return d_writer;
}

dal_ret_t dal_publisher_delete_datawriter(dal_publisher_t* pub, dal_datawriter_t* writer)
{
    DDS_Publisher* r_pub = get_rtidds_publisher(pub);
    if (!r_pub) {
        LOG_ERROR_WITH_LOCATION() << "get rtidds publisher failed." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DDS_DataWriter* r_writer = get_rtidds_datawriter(writer);
    if (!r_writer) {
        LOG_ERROR_WITH_LOCATION() << "rtidds datawriter is invalid." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DDS_ReturnCode_t ret = DDS_Publisher_delete_datawriter(r_pub, r_writer);
    if (DDS_RETCODE_OK != ret) {
        LOG_ERROR_WITH_LOCATION() << "delete datawriter failed." << LOG_ENDL;
        return DAL_RETCODE_ERROR;
    }

    EntityMappingRemoveDataWriter(r_writer);

    DalDataWriterImpl* writer_impl = reinterpret_cast<DalDataWriterImpl*>(writer->handle_);
    delete writer_impl;
    dal_datawriter_free(writer);
    reinterpret_cast<dal_datawriter_t*>(writer)->handle_ = nullptr;

    return DAL_RETCODE_OK;
}

dal_ret_t dal_datawriter_write(dal_datawriter_t* writer,
                               dal_data data,
                               dal_instance_handle_t handle = DAL_HANDLE_NIL)
{
    DDS_DataWriter* r_writer = get_rtidds_datawriter(writer);
    if (!r_writer) {
        LOG_ERROR_WITH_LOCATION() << "rtidds datawriter is invalid." << LOG_ENDL;
        return DAL_RETCODE_BAD_PARAMETER;
    }

    DDS_InstanceHandle_t r_handle;
    dal_ret_t d_ret = InstanceHandleConverter::GetInstance()->ConvertInstanceHandleFromDalToRtidds(
        &handle, &r_handle);
    if (DAL_RETCODE_OK != d_ret)
        return d_ret;

    const RtiTypeSupportImpl* tsImpl =
        reinterpret_cast<const RtiTypeSupportImpl*>(writer->type_support_impl_);
    DAL_Connext_MessageTypeSupport* ts = tsImpl->cxtMsgTs_;
    // {0，0，0，0} is bad.
    r_handle = DDS_HANDLE_NIL;
    DAL_Connext_Message user_msg;
    if (DAL_RET_OK != DAL_Connext_Message_initialize(&user_msg, ts, 0)) {
        LOG_ERROR_WITH_LOCATION() << "DAL_Connext_Message_initialize failed." << LOG_ENDL;
        return DAL_RETCODE_ERROR;
    }
    user_msg.user_data = data;
    user_msg.serialized = false;
    if (DDS_DataWriter_write_untypedI(r_writer, &user_msg, &r_handle) != DDS_RETCODE_OK) {
        return DAL_RETCODE_ERROR;
    }
    return DAL_RETCODE_OK;
}

dal_guid_t dal_datawriter_get_guid(dal_datawriter_t* writer)
{
    dal_guid_t d_guid = { };
    DDS_GUID_t r_guid;
    DDS_InstanceHandle_t r_ins_handle;

    DDS_DataWriter* r_writer = get_rtidds_datawriter(writer);
    if (!r_writer) {
        LOG_ERROR_WITH_LOCATION() << "rtidds datawriter is invalid." << LOG_ENDL;
        return d_guid;
    }

    r_ins_handle = DDS_Entity_get_instance_handle(DDS_DomainParticipant_as_entity(r_writer));

    memcpy(r_guid.value, r_ins_handle.keyHash.value, DDS_GUID_LENGTH);
    GuidConverter::GetInstance()->ConvertGuidFromRtiddsToDal(&r_guid, &d_guid);
    return d_guid;
}
